﻿//-----------------------------------------------------------------------
// <copyright file="ActivityFeedDataSource.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation 2011.
// All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Yogesh M Joshi</author>
// <date>02-10-2011</date>
// <summary></summary>
//-----------------------------------------------------------------------

namespace SPActivityFeed.DataSources
{
    using System;
    using System.Data;
    using System.ServiceModel.Syndication;
    using System.Xml;
    using System.Xml.Linq;
    using Microsoft.Office.Server.ActivityFeed;
    using Microsoft.Office.Server.UserProfiles;
    using Microsoft.SharePoint;
    using System.Globalization;

    class ActivityFeedDataSource
    {
        /// <summary>
        /// User Profile Manager object
        /// </summary>
        private UserProfileManager userProfileManager;

        /// <summary>
        /// Activity Manager object
        /// </summary>
        private ActivityManager activityManager;

        /// <summary>
        /// Activity events collection
        /// </summary>
        private ActivityEventsCollection activityEvents;

        /// <summary>
        /// Error text to be displayed
        /// </summary>
        private string errorText = string.Empty;

        /// <summary>
        /// True if there is any error
        /// </summary>
        private bool error = false;

        /// <summary>
        /// Initializes a new instance of the ActivityFeedDataSource class
        /// </summary>
        /// <param name="currentUser">Requesting user</param>
        public ActivityFeedDataSource(SPUser currentUser)
        {
            string siteUrl = SPContext.Current.Site.Url;

            SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(delegate
            {
                using (SPSite site = new SPSite(siteUrl))
                {
                    try
                    {
                        SPServiceContext context = SPServiceContext.GetContext(site);
                        this.userProfileManager = new UserProfileManager(context);
                        UserProfile profile = this.userProfileManager.GetUserProfile(currentUser.LoginName);
                        this.activityManager = new ActivityManager(profile, context);
                    }
                    catch (UserNotFoundException ex)
                    {
                        this.error = true;
                        this.errorText = ex.Message;
                    }
                    catch (NullReferenceException ex)
                    {
                        this.error = true;
                        this.errorText = ex.Message;
                    }
                }
            }));
        }

        /// <summary>
        /// Load activities for current user
        /// </summary>
        /// <param name="maxEvents">Maximum events to load</param>
        public void LoadActivitiesForMe(int maxEvents)
        {
            if (this.error)
            {
                return;
            }

            this.activityEvents = this.activityManager.GetActivitiesForMe(maxEvents);
        }

        /// <summary>
        /// Load activities done by current user
        /// </summary>
        public void LoadActivitiesByMe()
        {
            if (this.error)
            {
                return;
            }

            this.activityEvents = this.activityManager.GetActivitiesByMe();
        }

        /// <summary>
        /// Load activities done by specified user
        /// </summary>
        public void LoadActivitiesByUser()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Returns the result in xml format
        /// </summary>
        /// <returns>Result Xml</returns>
        public XElement GetDataXml()
        {
            XElement root = new XElement("Root");

            using (XmlWriter writer = root.CreateWriter())
            {
                if (string.IsNullOrEmpty(this.errorText) == false)
                {
                    XElement err = new XElement("Error");
                    err.SetValue(this.errorText);
                    err.WriteTo(writer);
                    return root;
                }

                using (DataTable table = this.GetDataTable())
                {
                    if (table.Rows.Count == 0)
                    {
                        XElement noResults = new XElement("NoResults");
                        noResults.SetValue("There are no recent activites.");
                        noResults.WriteTo(writer);

                        return root;
                    }

                    table.WriteXml(writer, XmlWriteMode.IgnoreSchema, true);
                }

                XElement seeAllLink = new XElement("ViewAllLink");
                seeAllLink.SetValue(this.userProfileManager.MySiteHostUrl);
                seeAllLink.WriteTo(writer);
            }

            return root;
        }

        /// <summary>
        /// Get the data in format of the data table
        /// </summary>
        /// <returns>Activity data table</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
        public DataTable GetDataTable()
        {
            DataTable table = new DataTable("Item");
            SyndicationItem syndicationItem = null;
            string imageUrl = string.Empty;

            table.Columns.Add("Email");
            table.Columns.Add("PersonProfileImageUrl");
            table.Columns.Add("PersonProfileUrl");
            table.Columns.Add("PersonName");
            table.Columns.Add("ActivitySummary");
            table.Columns.Add("ActivityDate");

            foreach (ActivityEvent activityEvent in this.activityEvents)
            {
                syndicationItem = activityEvent.CreateSyndicationItem(this.activityManager.ActivityTypes, ContentType.Html);
                imageUrl = activityEvent.Publisher.Picture;

                DataRow row = table.NewRow();
                row["Email"] = activityEvent.Publisher.Email;
                row["PersonProfileImageUrl"] = string.IsNullOrEmpty(imageUrl) ?
                    "/_layouts/images/O14_person_placeHolder_32.png" :
                    imageUrl;
                row["PersonProfileUrl"] = activityEvent.Publisher.Href;
                row["PersonName"] = activityEvent.Publisher.Name;
                row["ActivitySummary"] = syndicationItem.Summary.Text;
                row["ActivityDate"] = activityEvent.PublishDate.HasValue ?
                    activityEvent.PublishDate.Value.ToLocalTime().ToString("dd MMM yyyy hh:mm tt") :
                    string.Empty;
                table.Rows.Add(row);
            }

            return table;
        }
    }
}
